﻿using System;
using System.Collections.Generic;
using Swift;
using Swift.Math;

namespace SCM
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public class UserInfo : SerializableData
    {
        // 钱币
        public int Coins;

        // 胜场次数
        public int WinCount;

        // 败场次数
        public int LoseCount;

        // 当前拥有的各类卡片等级和数量，卡片类型就是 UnitType 的类型
        public StableDictionary<string, KeyValuePair<int, int>> Cards = new StableDictionary<string, KeyValuePair<int, int>>();

        // 已经通关的 PVE 关卡
        List<string> PVEPassed = new List<string>();

        protected override void Sync()
        {
            BeginSync();

            if (IsWrite)
                WriteCards(W);
            else
                ReadCards(R);

            SyncInt(ref Coins);
            SyncInt(ref WinCount);
            SyncInt(ref LoseCount);
            SyncListString(ref PVEPassed);
            EndSync();
        }

        // 记录已经通关指定 PVE 关卡
        public void AddPassedPVELevel(string level)
        {
            if (!PVEPassed.Contains(level))
                PVEPassed.Add(level);
        }

        // 是否已经通关指定 PVE 关卡
        public bool PassedPVE(string level)
        {
            return PVEPassed.Contains(level);
        }

        public void WriteCards(IWriteableBuffer w)
        {
            w.Write(Cards.KeyArray.Length);
            foreach (var c in Cards.KeyArray)
            {
                w.Write(c);
                var num = Cards[c].Key;
                var lv = Cards[c].Value;
                w.Write(num);
                w.Write(lv);
            }
        }

        public void ReadCards(IReadableBuffer r)
        {
            FC.For(r.ReadInt(), (i) =>
            {
                var c = r.ReadString();
                var num = r.ReadInt();
                var lv = r.ReadInt();
                Cards[c] = new KeyValuePair<int, int>(num, lv);
            });
        }

        public int GetCardLv(string c)
        {
            return Cards.ContainsKey(c) ? Cards[c].Value : 0;
        }

        public int GetCardNum(string c)
        {
            return Cards.ContainsKey(c) ? Cards[c].Key : 0;
        }

        // 获取当前用户能用指定建筑建造的兵种
        public string[] GetInBuildingUnit(string buildingType)
        {
            var cfg = UnitConfiguration.GetDefaultConfig(buildingType);
            if (!cfg.NeutralType) // 非中立单位必须自己先拥有才能建造
            {
                if (!Cards.ContainsKey(buildingType) || Cards[buildingType].Value <= 0 /* level */)
                    return new string[0];
            }

            var lst = new List<string>();
            foreach (var c in cfg.GenUnitTypes)
            {
                var lv = GetCardLv(c);
                if (lv <= 0 || !UnitConfiguration.GetDefaultConfig(c).IsBuilding)
                    continue;

                lst.Add(c);
            }

            return lst.ToArray();
        }

        public string[] GetBuildingLevelUp(string buildingType)
        {
            if (!Cards.ContainsKey(buildingType) || Cards[buildingType].Value <= 0 /* level */)
                return new string[0];

            var lst = new List<string>();
            var cfg = UnitConfiguration.GetDefaultConfig(buildingType);
            if (cfg != null && cfg.LevelUps != null)
            {
                foreach (var c in cfg.LevelUps)
                {
                    var lv = GetCardLv(c);
                    if (lv <= 0)
                        continue;

                    lst.Add(c);
                }
            }

            // lst.Add("Recycle");
            return lst.ToArray();
        }

        public string[] AllCanBuildOnEmptyGround
        {
            get
            {
                var lst = new List<string>();
                foreach (var c in Cards.KeyArray)
                {
                    var cfg = UnitConfiguration.GetDefaultConfig(c);
                    if (c == "CommanderCenter" || cfg.LevelUpFrom != null || !cfg.IsBuilding || cfg.IsAccessory || cfg.NoBody)
                        continue;

                    var lv = GetCardLv(c);
                    if (lv <= 0)
                        continue;

                    lst.Add(c);
                }

                return lst.ToArray();
            }
        }

        // 直接添加单位
        public void AddUnit(string unitType, int lv = 1)
        {
            if (GetCardLv(unitType) > 0)
                throw new Exception("unit " + unitType + " already exists");
            else if (lv <= 0)
                throw new Exception("unit level should be positive number");

            var num = GetCardNum(unitType);
            Cards[unitType] = new KeyValuePair<int, int>(num, 1);
        }

        // 添加卡片
        public void AddCard(string unitType, int n)
        {
            var num = Cards.ContainsKey(unitType) ? Cards[unitType].Key : 0;
            var lv = Cards.ContainsKey(unitType) ? Cards[unitType].Value : 0;

            num += n;
            num = num < 0 ? 0 : num;
            Cards[unitType] = new KeyValuePair<int, int>(num, lv);
        }

        // 合成或升级单位
        public bool CombineOrUpgradeUnit(string c)
        {
            var num = GetCardNum(c);
            var lv = GetCardLv(c);
            var cardsCost = UnitConfiguration.GetDefaultConfig(c).CardsCost;

            if (cardsCost == null || lv >= cardsCost.Length || num < cardsCost[lv])
                return false;

            num -= cardsCost[lv];
            Cards[c] = new KeyValuePair<int, int>(num, lv + 1);
            return true;
        }

        // 创建特殊的 UserInfo 对象，所有单位全开，等级都是 1
        public static UserInfo CreateAllLevel1UserInfo()
        {
            var aiUsrInfo = new UserInfo();
            foreach (var c in UnitConfiguration.AllConfigNames)
            {
                var cfg = UnitConfiguration.GetDefaultConfig(c);
                if (cfg.NeutralType)
                    continue;

                aiUsrInfo.AddUnit(c, 1);
            }

            return aiUsrInfo;
        }
    }
}
